home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_4.3 / XCP / XCP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  6.4 KB  |  297 lines

  1. /* 
  2.  * xcp.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /*
  10.  * XBDY
  11.  *
  12.  * detection and encoding of planar boundaries in given image,
  13.  * implementing an algorithm by C. T. Zahn [1969]
  14.  *
  15.  */
  16. #include "xcp.h"
  17.  
  18.  
  19. #define    WINDOW_ROWS    3
  20. #define NDIRECTIONS    8
  21.  
  22. #define    THRESH        1
  23. #define MIN_POLY_SIZE    20
  24. #define    ZERO        0
  25. #define ROOT2        1.414213562
  26.  
  27. #define    NA_MAX        128             /* lim of points, see ph.c */
  28.  
  29. #define    ON        1
  30. #define    OFF        0
  31.  
  32. #define    RESET        ON
  33. #define NO_RESET    OFF
  34.  
  35. #undef    DEBUG
  36. #undef    SHOW_CURV_PT
  37.  
  38.  
  39. /* global variables */
  40. extern short tiffInput;         /* flag=0 if no ImageIn to set tags; else =1 */
  41. struct curv_points *curv_head_in[NDIRECTIONS];
  42. struct curv_points *curv_head_out[NDIRECTIONS];
  43. struct curv_points *curv_tail_in[NDIRECTIONS];
  44. struct curv_points *curv_tail_out[NDIRECTIONS];
  45.  
  46. struct polygon *poly_head_ptr;
  47. struct polygon *poly_tail_ptr;
  48. float *delta_phik, *delta_lk;
  49.  
  50. long ncp = 0;
  51.  
  52. int loop_switch = ON;           /* enable/disable loop for polyg. approx */
  53. int hull_switch = ON;           /* enable/disable eval of convex hull */
  54. int n_ap_max = NA_MAX;          /* max no allowed vertices in approx. poly */
  55.  
  56. extern char *optarg;
  57. extern int optind, opterr;
  58. char *in_filename;
  59.  
  60. /*
  61.  * usage of routine
  62.  */
  63. void
  64. usage (char *progname)
  65. {
  66.   progname = last_bs (progname);
  67.   printf ("USAGE: %s inimg [-L]\n", progname);
  68.   printf ("\n%s detects and encodes contours, or planar boundaries, of regions\n", progname);
  69.   printf ("in a binary image implementing an algorithm by C. T. Zahn [1969]\n\n");
  70.   printf ("ARGUMENTS:\n");
  71.   printf ("       inimg: input image filename (TIF)\n\n");
  72.   printf ("OPTIONS:\n");
  73.   printf ("          -L: print Software License for this module\n");
  74.  
  75.   exit (1);
  76. }
  77.  
  78. void
  79. init_structs ()
  80. {
  81.   int m;
  82.  
  83.   for (m = 0; m < NDIRECTIONS; m++) {
  84.     curv_tail_in[m] = curv_tail_out[m] = NULL;
  85.     curv_head_in[m] = curv_head_out[m] = NULL;
  86.   }
  87.   poly_head_ptr = NULL;
  88.   poly_tail_ptr = NULL;
  89. }
  90.  
  91. /*
  92.  * acquire first three rows from input image
  93.  * and transfer them to the window
  94.  */
  95. void
  96. xfer_first_3_rows (unsigned char *window[], Image * imgIO)
  97. {
  98.   int ir;
  99.  
  100.   for (ir = 0; ir < 3; ir++)
  101.     getrow (*(window + ir), ir, imgIO);
  102. }
  103.  
  104. /*
  105.  * acquire next from input image
  106.  * and transfer it to the window
  107.  */
  108. void
  109. xfer_next_row (unsigned char *window[], int ir, Image * imgIO)
  110. {
  111.   int y;
  112.   unsigned char *char_ptr;
  113.  
  114.   char_ptr = *(window + (ir % WINDOW_ROWS));
  115.   y = ir + 3;                   /* offset of 3 from first_3_rows */
  116.   getrow (char_ptr, y, imgIO);
  117. }
  118.  
  119. /*
  120.  * zero border error message
  121.  */
  122. void
  123. border_err (int row, int col)
  124. {
  125.   printf ("...AOI border not zeroed at row %d, col %d\n", row, col);
  126.   exit (1);
  127. }
  128.  
  129. /*
  130.  * image border must be zeroed -- check it!
  131.  */
  132. void
  133. check_border (unsigned char *window[], int ir, int jmax, int imax, Image * imgIO)
  134. {
  135.   int jc;
  136.   unsigned char *char_ptr;
  137.  
  138.   if (ir == 0) {
  139.     char_ptr = *(window + (ir % WINDOW_ROWS));
  140.     for (jc = 0; jc < jmax; jc++)
  141.       if (*(char_ptr + jc) != ZERO)
  142.         border_err (ir, jc);
  143.   }
  144.   if (ir == (imax - WINDOW_ROWS)) {
  145.     char_ptr = *(window + ((ir + 0) % WINDOW_ROWS));
  146.     if (*(char_ptr) != ZERO)
  147.       border_err (ir, 0);
  148.     if (*(char_ptr + (jmax - 1)) != ZERO)
  149.       border_err (ir, jmax - 1);
  150.  
  151.     char_ptr = *(window + ((ir + 1) % WINDOW_ROWS));
  152.     if (*(char_ptr) != ZERO)
  153.       border_err (ir + 1, 0);
  154.     if (*(char_ptr + (jmax - 1)) != ZERO)
  155.       border_err (ir + 1, jmax - 1);
  156.  
  157.     char_ptr = *(window + ((ir + 2) % WINDOW_ROWS));
  158.     for (jc = 0; jc < jmax; jc++)
  159.       if (*(char_ptr + jc) != ZERO)
  160.         border_err (ir + 2, jc);
  161.   }
  162.   else {
  163.     char_ptr = *(window + (ir % WINDOW_ROWS));
  164.     if (*(char_ptr) != ZERO)
  165.       border_err (ir, 0);
  166.     if (*(char_ptr + (jmax - 1)) != ZERO)
  167.       border_err (ir, jmax - 1);
  168.   }
  169. }
  170.  
  171. /*
  172.  * memory allocation for image (one row at a time)
  173.  */
  174. int
  175. img_alloc (unsigned char *img[], int nr, int nc)
  176. {
  177.   int ir;
  178.  
  179.   for (ir = 0; ir < nr; ir++) {
  180.     if ((*(img + ir) = (unsigned char *) calloc (nc, sizeof (unsigned char))) == NULL)
  181.         return (0);
  182.     else
  183.       *(img + ir) += 0;
  184.  
  185.   }
  186.   return (1);
  187. }
  188.  
  189.  
  190. void
  191. main (int argc, char *argv[])
  192. {
  193.   unsigned char *window[WINDOW_ROWS];
  194.   int ir;
  195.   int nr, nc;
  196.   int jmin, imin, jmax, imax;
  197.   int left_x, right_x;
  198.   float *delta_phikp, *delta_lkp;
  199.   Image *imgIn;                 /* input image */
  200.   Image *imgOut = NULL;         /* output image not (used in this program) */
  201.   int i_arg;
  202.  
  203. /*
  204.  * cmd line options
  205.  */
  206.   static char *optstring = "c:bL";
  207.  
  208.  
  209. /*
  210.  * parse command line
  211.  */
  212.   optind = 2;                   /* set getopt to point to the 3rd arg */
  213.   opterr = ON;                  /* give error messages */
  214.  
  215.  
  216.   if (argc < 2)
  217.     usage (argv[0]);
  218.  
  219.   while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
  220.     switch (i_arg) {
  221.     case 'L':
  222.       print_sos_lic ();
  223.       exit (0);
  224.     default:
  225.       printf ("\ngetopt: unknown condition encountered\n");
  226.       exit (1);
  227.       break;
  228.     }
  229.   }
  230. /*
  231.  * initialize structures
  232.  */
  233.   init_structs ();
  234.  
  235. /*
  236.  * get the input image
  237.  */
  238.   imgIn = ImageIn (argv[1]);
  239.   if (imgIn->bps == 8 && imgIn->spp == 3) {
  240.     printf ("Got RGB image!!!\n");
  241.     fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
  242.     exit (1);
  243.   }
  244.   in_filename = argv[1];
  245.  
  246.   jmin = imin = 0;
  247.   jmax = imgIn->width;
  248.   imax = imgIn->height;
  249.  
  250.   left_x = jmin;
  251.   right_x = jmax - 1;
  252.   nc = jmax - jmin;
  253.   nr = imax - imin;
  254.  
  255. #ifdef DEBUG
  256.   printf ("\n...nc = %d, nr = %d\n", nc, nr);
  257. #endif
  258.  
  259. /*
  260.  *  zero outer border of image
  261.  */
  262.   zero_border (imgIn, 2);
  263.  
  264. /*
  265.  * allocate memory
  266.  */
  267.   if ((img_alloc (window, WINDOW_ROWS, nc) == 0))
  268.     exitmess ("window", 1);
  269.  
  270.   printf ("\n...scan image...\n");
  271.   xfer_first_3_rows (window, imgIn);
  272.   for (ir = 0; ir < imax - WINDOW_ROWS; ir++) {
  273.     check_border (window, ir, jmax, imax, imgIn);
  274.     curvature_points (window, ir, jmax, imax);
  275.     xfer_next_row (window, ir, imgIn);
  276.   }
  277.   check_border (window, ir, jmax, imax, imgIn);
  278.   curvature_points (window, ir, jmax, imax);
  279.  
  280.  
  281.   if ((delta_phikp = (float *) calloc (ncp, sizeof (float))) == NULL)
  282.       exitmess ("delta_phik", 1);
  283.   if ((delta_lkp = (float *) calloc (ncp, sizeof (float))) == NULL)
  284.       exitmess ("delta_phik", 1);
  285.   delta_phik = delta_phikp;
  286.   delta_lk = delta_lkp;
  287.  
  288. /*
  289.  * construct lists representing individual boundaries
  290.  */
  291.   printf ("...construct linked lists of boundary points...\n");
  292.   linkage (imgIn, imgOut, WHITE);
  293.  
  294.   free (delta_phikp);
  295.   free (delta_lkp);
  296. }
  297.